#ifndef NASCCL_Initialize_Cpp
#define NASCCL_Initialize_Cpp
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
    The InitializeCryptographySet function is used to get your Key, Size Of Key,
    & encryption attributes ready for the Encode / Decode routines.

    This function must be called before every "Set" of data you wish to Encode / Decode.
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <Windows.H>

#include "NASCCL.H"
#include "sBoxes.H"
#include "Math.H"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

bool NASCCL::InitializeCryptographySet(void *inUserKey, int inUserKeyLen, int inAttribute)
{
    int LocalLoop = 0;
    int KeyLoop   = 0;
    int Box       = 0;

    NASCCLByte SKey = 0;

    if(inUserKeyLen > MaxKeyLength) return false;
    if(inUserKeyLen < MinKeyLength) return false;

    Attribute  = inAttribute;
    KeyHashLen = inUserKeyLen;
    KeyHashPos = 0;

    KeyHash = (NASCCLByte *) calloc( sizeof(NASCCLByte), inUserKeyLen + 1);

    if(Attribute &CIPHERUSERSKEY)
        CipherKey(inUserKey, KeyHash, inUserKeyLen);
    else memcpy(KeyHash, inUserKey, inUserKeyLen);

    memset(&MValue, 0, sizeof(MValue));
    memset(&Matrix, 0, sizeof(Matrix));

    while(LocalLoop < KeyHashLen)
    {
        SKey = sKeyBox[Box][ ((NASCCLByte *)inUserKey)[LocalLoop] ];

        KeyLoop = 0;

        if(Attribute &CRYPTFULLDATASET) // If NOT crypting full data set then initialize Matrix
        {
            while(KeyLoop != 6)
            {
                Matrix[KeyLoop][0] += ((((NASCCLByte *)KeyHash)[LocalLoop] ^ 61) + SKey);
                Matrix[KeyLoop][1] += ((((NASCCLByte *)KeyHash)[LocalLoop] ^ 52) + SKey);
                Matrix[KeyLoop][2] += ((((NASCCLByte *)KeyHash)[LocalLoop] ^ 43) + SKey);
                Matrix[KeyLoop][3] += ((((NASCCLByte *)KeyHash)[LocalLoop] ^ 34) + SKey);
                Matrix[KeyLoop][4] += ((((NASCCLByte *)KeyHash)[LocalLoop] ^ 25) + SKey);
                Matrix[KeyLoop][5] += ((((NASCCLByte *)KeyHash)[LocalLoop] ^ 16) + SKey);
                KeyLoop++;
            }
        }
        else{  // If crypting full data set then initialize MValue

            while(KeyLoop != 6)
            {
                MValue[KeyLoop][0] += ((((NASCCLByte *)KeyHash)[LocalLoop] ^ 16) + SKey);
                MValue[KeyLoop][1] += ((((NASCCLByte *)KeyHash)[LocalLoop] ^ 25) + SKey);
                MValue[KeyLoop][2] += ((((NASCCLByte *)KeyHash)[LocalLoop] ^ 34) + SKey);
                MValue[KeyLoop][3] += ((((NASCCLByte *)KeyHash)[LocalLoop] ^ 43) + SKey);
                MValue[KeyLoop][4] += ((((NASCCLByte *)KeyHash)[LocalLoop] ^ 52) + SKey);
                MValue[KeyLoop][5] += ((((NASCCLByte *)KeyHash)[LocalLoop] ^ 61) + SKey);
                KeyLoop++;
            }
        }

        if(Box == 64) Box = -1;
        
        Box++;
        LocalLoop++;
    }

    return true;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif

